using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Iesi.Collections.Generic;
using Ornament.Domain;
using Ornament.MemberShip.Permissions;

namespace Ornament.MemberShip
{
    [Serializable]
    public class Role : DomainObject<Guid>, IPerformer
    {
        private string _remark;
        private string _name;

        private Iesi.Collections.Generic.ISet<Permission> permissions;

        public Role()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleName"></param>
        public Role(string roleName)
        {
            if (roleName == null)
                throw new ArgumentNullException("roleName");
            Name = roleName;
        }

        /// <summary>
        /// 
        /// </summary>
        [Display(Name = "Name", ResourceType = typeof(Languages.MemberShip))]
        [Required(ErrorMessageResourceType = typeof(Languages.ErrorMessage), ErrorMessageResourceName = "RequireRoleName")]
        [StringLength(20, ErrorMessageResourceType = typeof(Languages.ErrorMessage), ErrorMessageResourceName = "RoleNameOverMaxLength")]
        public string Name
        {
            get { return _name; }
            set
            {
                if (!String.IsNullOrEmpty(_name) && value != _name)
                    throw new ArgumentException("Name only set once");
                if (String.IsNullOrEmpty(value))
                    throw new ArgumentNullException("value", "Name can't be empty");
                if (value.Length > 20)
                    throw new ArgumentOutOfRangeException("value", value.Length, "Name's lenght over than 20");
                _name = value.ToLower();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [Display(Name = "Remark", ResourceType = typeof(Languages.MemberShip))]
        [StringLength(100, ErrorMessageResourceType = typeof(Languages.ErrorMessage), ErrorMessageResourceName = "RoleRemarkOverMaxLength")]
        public string Remark
        {
            get { return _remark; }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    if (value.Length > 100)
                    {
                        throw new ArgumentOutOfRangeException("value", value.Length,
                                                              "Comment 's length should be less than 100");
                    }
                    _remark = value;
                }
            }
        }

        public Iesi.Collections.Generic.ISet<Permission> Permissions
        {
            get { return permissions ?? (permissions = new HashedSet<Permission>()); }
        }

        #region IPerformer Members

        IList<User> IPerformer.GetUsers(IMemberShipFactory factory)
        {
            return factory.CreateUserDao().GetUsersInRole(Name);
        }

        string IPerformer.Name
        {
            get { return _name; }
        }

        #endregion

        public override int GetHashCode()
        {
            return (Name + Remark).GetHashCode();

        }
    }
}